/**
 *
 */
package com.ruoyi.activity.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruoyi.activity.domain.ActBusinessFlowRel;
import com.ruoyi.activity.domain.ActHistoricTaskInstanceInfo;
import com.ruoyi.activity.service.IActBusinessFlowRelService;
import com.ruoyi.activity.service.IActHistoryTaskService;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.system.domain.CompanyInfo;
import com.ruoyi.system.service.ICompanyInfoService;
import com.ruoyi.system.service.ISysUserService;
import org.activiti.engine.HistoryService;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.history.HistoricVariableInstance;
import org.activiti.engine.impl.persistence.entity.HistoricTaskInstanceEntityImpl;
import org.activiti.engine.impl.persistence.entity.TaskEntityImpl;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.task.Task;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
* 操作历史节点
*/
@Service
public class ActHistoryTaskService implements IActHistoryTaskService {

	@Resource
	protected HistoryService historyService;

	@Autowired
	private ISysUserService sysUserService;

	@Autowired
	private ICompanyInfoService companyInfoServiceImpl;

	@Resource
	protected RepositoryService repositoryService;

	@Autowired
	private IActBusinessFlowRelService actBusinessFlowRelService;

	@Override
	public List<ActHistoricTaskInstanceInfo> listHistoryTaskNodes(String instanceId) {
		List<HistoricTaskInstance>  tasks =  historyService.createHistoricTaskInstanceQuery().processInstanceId(instanceId).orderByHistoricTaskInstanceStartTime().asc().list();
		if(!CollectionUtils.isEmpty(tasks)) {
			List<ActHistoricTaskInstanceInfo> result = new ArrayList<ActHistoricTaskInstanceInfo>(tasks.size());
			for (HistoricTaskInstance task : tasks) {
				result.add(convertHistoricTask(task));
			}
			return result;
		}
		return null;
	}


	@Override
	public ActHistoricTaskInstanceInfo convertHistoricTask(HistoricTaskInstance historicTask) {

		HistoricTaskInstanceEntityImpl taskInstanceEntity = (HistoricTaskInstanceEntityImpl) historicTask;
		ActHistoricTaskInstanceInfo taskInstanceInfo =new ActHistoricTaskInstanceInfo();
		BeanUtil.copyProperties(taskInstanceEntity, taskInstanceInfo);

		Long assigneeUserId = StringUtils.isNotBlank(historicTask.getAssignee())?Long.parseLong(historicTask.getAssignee()):null;
		SysUser assigneeUser = sysUserService.selectUserById(assigneeUserId);
		if(assigneeUser != null){
			taskInstanceInfo.setAssigneeName(assigneeUser.getNickName());
			CompanyInfo companyInfo = companyInfoServiceImpl.selectCompanyInfoByUserId(historicTask.getAssignee());
			if(companyInfo != null && "true".equals(companyInfo.getRegisterStatus())){
				taskInstanceInfo.setAssigneeUserCompany(companyInfo.getCompanyName());
			}
		}
		HistoricProcessInstance instance = historyService.createHistoricProcessInstanceQuery()
				.processInstanceId(historicTask.getProcessInstanceId()).singleResult();

		taskInstanceInfo.setBusinessKey(instance.getBusinessKey());
		Long startUserId = StringUtils.isNotBlank(instance.getStartUserId())?Long.parseLong(instance.getStartUserId()):null;
		SysUser applyUser = sysUserService.selectUserById(startUserId);
		taskInstanceInfo.setApplyUserId(instance.getStartUserId());
		if(applyUser!=null) {
			taskInstanceInfo.setApplyUserName(applyUser.getUserName());
		}
		ProcessDefinition definition = repositoryService.createProcessDefinitionQuery()
				.processDefinitionId(historicTask.getProcessDefinitionId()).singleResult();
		taskInstanceInfo.setProcessDefinitionId(definition.getId());
		taskInstanceInfo.setProcessDefinitionName(definition.getName());
		taskInstanceInfo.setProcessDefinitionKey(definition.getKey());


		List<HistoricVariableInstance> variables = historyService.createHistoricVariableInstanceQuery().processInstanceId(historicTask.getProcessInstanceId()).list();
		Map<String,Object> variablesMap = new HashMap<String, Object>();
		if(!CollectionUtils.isEmpty(variables)) {
			for (HistoricVariableInstance v : variables) {
				if(v.getTaskId() != null && v.getTaskId().equals(historicTask.getId())){
					variablesMap.put(v.getVariableName(), v.getValue());
				}
			}
		}
		taskInstanceInfo.setProcessVariables(variablesMap);

		return taskInstanceInfo;
	}


	@Override
	public ActHistoricTaskInstanceInfo convertTask(Task task) {
		TaskEntityImpl taskEntity = (TaskEntityImpl) task;
		ActHistoricTaskInstanceInfo taskInstanceInfo =new ActHistoricTaskInstanceInfo();
		BeanUtil.copyProperties(taskEntity, taskInstanceInfo);
		SysUser assigneeUser = sysUserService.selectUserById(Long.parseLong(task.getAssignee()));
		if(assigneeUser!=null) {
			taskInstanceInfo.setAssigneeName(assigneeUser.getUserName());
		}

		ActHistoricTaskInstanceInfo historyTaskNodes = this.historyTaskNodes(task.getId());
		taskInstanceInfo.setStartTime(historyTaskNodes.getStartTime());
		taskInstanceInfo.setEndTime(historyTaskNodes.getEndTime());

		HistoricProcessInstance instance = historyService.createHistoricProcessInstanceQuery()
				.processInstanceId(task.getProcessInstanceId()).singleResult();
		taskInstanceInfo.setBusinessKey(instance.getBusinessKey());
		String processDefinitionKey = instance.getProcessDefinitionKey();
		//获取业务类型
		ActBusinessFlowRel one = actBusinessFlowRelService.getOne(Wrappers.<ActBusinessFlowRel>lambdaQuery()
				.eq(ActBusinessFlowRel::getFlowKey, processDefinitionKey)
				.eq(ActBusinessFlowRel::getBusinessId, instance.getBusinessKey()));
		if(null!=one){
			taskInstanceInfo.setBusinessType(one.getBusinessType());
		}
		SysUser applyUser = sysUserService.selectUserById(Long.parseLong(instance.getStartUserId()));
		taskInstanceInfo.setApplyUserId(instance.getStartUserId());
		if(applyUser!=null) {
			//String bdcode = applyUser.getBdcode();
			taskInstanceInfo.setApplyUserName(applyUser.getUserName());
		}

		ProcessDefinition definition = repositoryService.createProcessDefinitionQuery()
				.processDefinitionId(task.getProcessDefinitionId()).singleResult();
		taskInstanceInfo.setProcessDefinitionId(definition.getId());
		taskInstanceInfo.setProcessDefinitionName(definition.getName());
		taskInstanceInfo.setProcessDefinitionKey(definition.getKey());


		List<HistoricVariableInstance> variables = historyService.createHistoricVariableInstanceQuery().processInstanceId(task.getProcessInstanceId()).list();
		Map<String,Object> variablesMap = new HashMap<String, Object>();
		if(!CollectionUtils.isEmpty(variables)) {
			for (HistoricVariableInstance v : variables) {
				variablesMap.put(v.getVariableName(), v.getValue());
			}
		}
		taskInstanceInfo.setProcessVariables(variablesMap);

		return taskInstanceInfo;
	}


	@Override
	public ActHistoricTaskInstanceInfo historyTaskNodes(String taskId) {
		List<HistoricTaskInstance>  tasks =  historyService.createHistoricTaskInstanceQuery().taskId(taskId).orderByHistoricTaskInstanceStartTime().asc().list();
		if(!CollectionUtils.isEmpty(tasks)) {
			List<ActHistoricTaskInstanceInfo> result = new ArrayList<>(tasks.size());
			for (HistoricTaskInstance task : tasks) {
				result.add(convertHistoricTask(task));
			}
			return result.get(0);
		}
		return null;
	}


}
